make & Cmake

프로그램 소스와 컴파일된 라이브러리에서 애플리케이션과 라이브러리를 빌드할 때,
명령어를 입력하는 대신 적절한 도구를 사용해 빌드할 수 있다.
make
make의 기본 아이디어는 대상과 원본 간의 의존성을 표현하고,
대상이 원본보다 오래되었거나 누락되었을 경우 주어진 명령으로 대상을 생성한다.

makefile에 대상과 원본 간의 의존성을 작성하면,
make가 이를 해결해준다.

fluxer.cpp 소스를 fluxer.o 목적파일로 변환
fluxer.o: fluxer.cpp mesher.hpp solver.hpp
g++ fluxer.cpp -c -o fluxer.o
명령(들)이 있는 줄은 탭(\t)로 들여쓴다.

목적파일에 대한 규칙은 대부분 비슷하기 때문에 아래와 같이 일반적인 규칙으로 작성한다.
.cpp.o:
${CXX} ${CXXFLAGS} $^ -c -o $@
${CXX} 변수는  C++ 기본 컴파일러
${CXXFLAGS} 변수는 기본 플래그로 사전에 설정한다.
CXX=g++-5
CXXFLAGS= -O3 -DNDEBUG #
# CXXFLAGS= -O0 -g #
$@ 는 규칙의 대상을 가르킨다.
$” 는 규칙의 원본을 가르킨다.
$< 는 의존 파일 목록에 첫 번째 파일에 대응
$^ 는 의존 파일 목록 전체에 대응
$? 는 타겟 보다 최신의 의존 파일들에 대응
libmesher.a: mesher.o
ar cr $@ $"
libsolver.a: solver.o
ar cr $@ $"
링크
fluxer: fluxer.o libmersher.a libsovler.a
${CXX} ${CXXFLAGS} $" -o $@
이후, make 명령어를 통해서 실행할 수 있다.
make fluxer

이 후 아래의 작업이 순차적으로 진행된다.
g++ fluxer.cpp -c -o fluxer.o
g++ mesher.cpp -c -o mesher.o
ar cr libmersher.a mesher.o
g++ solver.cpp -c -o solver.o
ar cr libsolver.a solver.o
g++ fluxer.o libmesher.a libsolver.a -o fluxer

make는 일부 파일이 변경된 경우, 해당 파일에 의존하는 대상에 대해서만 다신 실행된다.
참고)
%를 사용해서 임의의 파일을 지정 가능
%.o: %.cpp %.hpp
${CXX} ${CXXFLAGS} -c $<
make 실행 디렉토리에 .cpp와 .hpp를 동시에 가지는 파일에 대하여 모두 컴파일
내부적으로 전처리 단계에서 .hpp 헤더 파일들이 사용될 것임
Cmake
Cmake는 make보다 높은 추상화 도구이다.
.txt 파일에 빌드 프로젝트(Cmake)를 지정하면 cmake 명령어를 통해 makefile을 생성해준다.
이 후, make 명령어를 통해 makefile를 빌드
CMakeLists.txt
cmake_minimum_required (VERSION 2.6)
project (Fluxer)
add_library(solver solver.cpp)
add_library(mesher SHARED mesher.cpp)
add_executable(fluxer fluxer.cpp)
target_link_libraries(fluxer solver mesher)
일반적으로 build라는 하위 디렉터리를 생성하고, 해당 디렉터리에서 모든 명령을 실행한다.

cd build
cmake ..

CMake는 플래그를 포함한 컴파일러와 다른 도구들을 검색하고,
makefile를 생성한다.

make
make와 동일하게 소스 파일이 변경된 경우, 변경 사항으로 인해 영향을 받는 부분만 다시 작성한다.
(makefile과 달리 헤더파일도 고려 대상임)

CMake의 가장 큰 장점은 이식성이다.
CMakeLists.txt 파일을 다른 생성기에 사용하면,
Visual Studio, Eclipse, Xcode 등의 프로젝트를 생성하는데 사용할 수 있다.